import astroH.LunarPhases;
import java.io.IOException;
import javax.microedition.midlet.*;

import com.sun.lwuit.*;
import com.sun.lwuit.animations.*;
import com.sun.lwuit.events.*;
import com.sun.lwuit.layouts.BoxLayout;
import com.sun.lwuit.plaf.UIManager;
import com.sun.lwuit.util.Resources;
import java.util.Date;

public class Moon extends MIDlet implements ActionListener {
    private Form now, phases, riseSet, settings, last;
    Command nextCmd, settingsCmd, backCmd, saveCmd, exitCmd;
    Label moon, vis;
    Image im, moon2;
    ButtonGroup modeButtons;
    RadioButton normalModeButton;
    RadioButton demoModeButton;
    RadioButton fixedModeButton;
    DateField dateTime;
    Resources res;
    LunarPhases lp;
    int dayOffset = 0;
    boolean demoMode = false, fixedMode = false;
     
    public void startApp() {
      if (now == null) {
        Display.init(this);
        lp = new LunarPhases();
        try {
            res = Resources.open("/theme.res");
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        UIManager.getInstance().setThemeProps(res.getTheme("Theme 1"));
        now = new Form("Now");
        phases = new Form("Phases");
        riseSet = new Form("Rise and Set");
        settings = new Form("Settings");
        settings.setLayout(new BoxLayout(BoxLayout.Y_AXIS));
        normalModeButton = new RadioButton("Realtime");
        demoModeButton = new RadioButton("Demo mode");
        fixedModeButton = new RadioButton("Fixed");
        modeButtons = new ButtonGroup();
        modeButtons.add(normalModeButton);
        modeButtons.add(demoModeButton);
        modeButtons.add(fixedModeButton);
        demoModeButton.addActionListener(this);
        fixedModeButton.addActionListener(this);
        normalModeButton.addActionListener(this);
        modeButtons.setSelected(normalModeButton);
        settings.addComponent(new Label("Mode:"));
        settings.addComponent(normalModeButton);
        settings.addComponent(demoModeButton);
        settings.addComponent(fixedModeButton);
        settings.addComponent(new Label("Fixed date/time:"));
        dateTime = new DateField(settings);
        settings.addComponent(dateTime);
        now.setTransitionOutAnimator(CommonTransitions.createSlide(CommonTransitions.SLIDE_HORIZONTAL, false, 500));
        phases.setTransitionOutAnimator(CommonTransitions.createSlide(CommonTransitions.SLIDE_HORIZONTAL, false, 500));
        riseSet.setTransitionOutAnimator(CommonTransitions.createSlide(CommonTransitions.SLIDE_HORIZONTAL, false, 500));
        settings.setTransitionOutAnimator(Transition3D.createRotation(500, true));
        nextCmd = new Command("Next");
        now.addCommand(nextCmd);
        now.setDefaultCommand(nextCmd);
        phases.addCommand(nextCmd);
        phases.setDefaultCommand(nextCmd);
        riseSet.addCommand(nextCmd);
        riseSet.setDefaultCommand(nextCmd);
        exitCmd = new Command("Exit");
        now.addCommand(exitCmd);
        phases.addCommand(exitCmd);
        riseSet.addCommand(exitCmd);
        now.setBackCommand(exitCmd);
        phases.setBackCommand(exitCmd);
        riseSet.setBackCommand(exitCmd);
        settingsCmd = new Command("Settings");
        now.addCommand(settingsCmd);
        phases.addCommand(settingsCmd);
        riseSet.addCommand(settingsCmd);
        saveCmd = new Command("Save");
        settings.addCommand(saveCmd);
        //settings.setDefaultCommand(saveCmd);
        backCmd = new Command("Back");
        settings.addCommand(backCmd);
        //settings.setBackCommand(backCmd);
        now.setCommandListener(this);
        phases.setCommandListener(this);
        riseSet.setCommandListener(this);
        settings.setCommandListener(this);
        //time = new Label("");
        //time.setAlignment(Label.CENTER);
        now.setLayout(new BoxLayout(BoxLayout.Y_AXIS));
        //now.addComponent(time);
        moon2 = res.getImage("Moon");
        im = Image.createImage(moon2.getWidth(), moon2.getHeight());
        moon = new Label(moon2);
        moon.setAlignment(Label.CENTER);
        now.addComponent(moon);
        vis = new Label("");
        vis.setAlignment(Label.CENTER);
        now.addComponent(vis);
        now.show();
        doUpdate();
        
        Thread timer = new Thread(){
                public void run() {
                    super.run();
                    while (true) {
                        doUpdate();
                        try {
                            sleep(500);
                        } catch (InterruptedException ex) {
                            ex.printStackTrace();
                        }
                    }
                }
        };
        timer.start();
      }
    }

    private void doUpdate() {
        if (demoMode) {
            lp.usingFixedDate = false;
            lp.offsetMillis = (long)dayOffset * 1000L * 60L * 60L * 24L;
            dayOffset++;
        }
        else if (fixedMode) {
            lp.usingFixedDate = true;
            lp.fixedDate = new Date(dateTime.getTime());
            lp.offsetMillis = 0L;
            dayOffset = 0;
        }
        else { // normal realtime mode
            lp.usingFixedDate = false;
            lp.offsetMillis = 0L;
            dayOffset = 0;
        }
        //time.setText(lp.gmt);
        now.setTitle(lp.gmt);
        vis.setText("Visible: " + lp.K + "%");
        lp.lunarPosition();
        lp.CalcLunarPhases();
        lp.getApogeePerigee();
        im.getGraphics().drawImage(moon2, 0, 0);
        lp.drawMoon(im.getGraphics(), lp.K, lp.year);
        moon.setIcon(im);
        if (Display.getInstance().getCurrent() != null) {
            Display.getInstance().getCurrent().repaint();
        }
    }
     
    private void doSaveSettings(boolean nextDemoMode) {
        demoMode = nextDemoMode;
        // TODO: Save settings to RMS
    }
    
    public void pauseApp() {}

    public void destroyApp(boolean unconditional) {}

    public void actionPerformed(ActionEvent ae) {
        boolean nextDemoMode = demoMode;
        Form current = Display.getInstance().getCurrent();
        if (ae.getSource() instanceof RadioButton) {
            if (((RadioButton)ae.getSource()).equals(normalModeButton) ||
            ((RadioButton)ae.getSource()).equals(fixedModeButton) ||
            ((RadioButton)ae.getSource()).equals(demoModeButton) ) {
                // TODO: shouldn't set demo/fixed mode now, but should wait until save is selected
                demoMode = (demoModeButton.isSelected());
                fixedMode = (fixedModeButton.isSelected());
            }
        } else {
            Command cmd = ae.getCommand();
            if (cmd == nextCmd) {
                if (current == now) {
                    phases.show();
                } else if (current == phases) {
                    riseSet.show();
                } else {
                    now.show();
                }
            } else if (cmd == settingsCmd) {
                current.setTransitionOutAnimator(Transition3D.createRotation(500, false));
                last = current;
                settings.show();
                current.setTransitionOutAnimator(CommonTransitions.createSlide(CommonTransitions.SLIDE_HORIZONTAL, false, 500));
            } else if (cmd == backCmd) {
                last.show();
            } else if (cmd == saveCmd) {
                doSaveSettings(nextDemoMode);
                last.show();
            } else if (cmd == exitCmd) {
                destroyApp(true);
                notifyDestroyed();
            }
        }
    }
}